// OpenZapper
// http://openzapper.codeplex.com/
// Appache License Version 2.0 



using System;
using Microsoft.SPOT;
using Microsoft.SPOT.IO;
using Microsoft.SPOT.Hardware;

using System.Collections;
using System.Text;

using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoPlus;
using SecretLabs.NETMF.IO;
using System.IO;

namespace OpenZapper
{
    public class ConfigReader
    {
        String SettingsFile;
        ArrayList Profiles  = new ArrayList();
        ArrayList ForbiddenFrequencies = new ArrayList();

        //default settings
        public long ActiveDuration  = 420;
        public long PauseDuration   = 1200;
        public int CyclesToDo       = 3;
        long BeepFrequency          = 10000;
        
        public ConfigReader(String Filename)
        {
            SettingsFile = @"SD\" + Filename;
            VolumeInfo[] vols = VolumeInfo.GetVolumes();
            foreach (VolumeInfo vi in vols)
            {
                Debug.Print(vi.RootDirectory.ToString());
                Debug.Print(vi.TotalFreeSpace.ToString());
                Debug.Print(vi.IsFormatted.ToString());
                Debug.Print(vi.VolumeID.ToString());
            }
        }

        private bool IsValidLine(string Line)
        {
            if (Line.Length > 0 && false == Line.Substring(0, 2).Equals("//"))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        private bool IsProfileSection(string line)
        {
            if (line.Length > 0 && line.IndexOf("[") >= 0 && line.IndexOf("//") == -1)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        private long CheckFoLongValue(string settingLine, string SettingName, long defaultValue)
        {
            long Value = defaultValue;
            if (settingLine.IndexOf(SettingName) >= 0)
            {
                try
                {
                    StringBuilder sb = new StringBuilder(settingLine);
                    String sVal = sb.Replace(SettingName, "").ToString();
                    Value = long.Parse(sVal);
                    return Value;
                }
                catch (Exception ex)
                {
                    Debug.Print("CheckFoLongValue error when loading setting " + SettingName  + " -> " + ex.Message);
                }
            }
            return -1;
        }
        public void LoadSettings()
        {
            if (File.Exists(SettingsFile) == true)
            {

                using (StreamReader sr = new StreamReader(SettingsFile))
                {
                    while (true)
                    {
                        string data = sr.ReadLine();

                        if (IsProfileSection(data))
                        {
                            break;
                        }
                        if (IsValidLine(data) && IsProfileSection(data) == false)
                        {
                            long val = CheckFoLongValue(data, "ActiveDuration=", 420);
                            if (val != -1)
                            {
                                ActiveDuration = val;
                                continue;
                            }
                            val = CheckFoLongValue(data, "PauseDuration=", 1200);
                            if (val != -1)
                            {
                                PauseDuration = val;
                                continue;
                            }
                            val = CheckFoLongValue(data, "CyclesToDo=", 3);
                            if (val != -1)
                            {
                                CyclesToDo = (int)val;
                                continue;
                            }
                            val = CheckFoLongValue(data, "BeepFrequency=", 10000);
                            if (val != -1)
                            {
                                BeepFrequency = val;
                                continue;
                            }
                        }
                    }
                }
            }
            LoadForbiddenFrequencies();
        }

        private void LoadForbiddenFrequencies()
        {
            const string forbiddenFrequenciesFilename = @"SD\forbidden_frequencies.txt";
            if (File.Exists(forbiddenFrequenciesFilename))
            {
                using (StreamReader sr = new StreamReader(forbiddenFrequenciesFilename))
                {

                    string data = sr.ReadLine();//reading first line //sequential or random
                    try
                    {
                        while (sr.BaseStream.Position <= sr.BaseStream.Length)
                        {
                            data = sr.ReadLine();
                            if (data.Length > 0)
                            {
                                long Frequency = 0;
                                try
                                {
                                    Frequency = long.Parse(data);
                                    ForbiddenFrequencies.Add(Frequency);
                                }
                                catch (Exception ex)
                                {
                                    Debug.Print(ex.Message);
                                }
                            }
                        }
                    }
                    catch (System.NullReferenceException)//happens when reaching end of file
                    {
                        Debug.Print("Reached end of Forbidden Frequencies file");
                    }
                    catch (Exception)
                    {
                        //Debug.Print(ex.Message);
                    }
                }
            }
        }
        public bool isForbiddenFrequency(long frequency)
        {
            if (ForbiddenFrequencies.Count == 0)
            {
                return false;
            }
            for (int i = 0; i < ForbiddenFrequencies.Count; i++)
            {
                if (frequency == (long)ForbiddenFrequencies[i])
                {
                    return true;
                }
            }
            return false;
        }

        public bool LoadProfiles()
        {
            String baseFolder = @"SD\Sequences\";
            if (Directory.Exists(baseFolder) == true)
            {
                string[] txtFiles = Directory.GetFiles(baseFolder);
                foreach (string filename in txtFiles)
                {
                    try
                    {
                        FileInfo fi = new FileInfo(filename);
                        if (fi.Extension == ".txt")
                        {
                            using (StreamReader sr = new StreamReader(filename))
                            {
                                bool bRandom = false;
                                string data = sr.ReadLine();//reading first line
                                if (data.IndexOf("Random") >= 0)
                                {
                                    bRandom = true;
                                }
                                StringBuilder sb = new StringBuilder(fi.Name);
                                sb.Replace(".txt", "");

                                Profiles.Add(new ZapperProfiles(sb.ToString(), bRandom));
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Debug.Print(ex.Message);
                    }
                }
                return true;
            }
            else
            {
                //load default profiles
                Profiles.Add(new ZapperProfiles("DEFAULT 1Khz", false));
                Profiles.Add(new ZapperProfiles("DEFAULT 2.5Khz", false));
                Profiles.Add(new ZapperProfiles("DEFAULT 30Khz", false));
                return false;
            }
        }
        public ArrayList getProfileData(ZapperProfiles profile)
        {
            ArrayList ProfilesData = new ArrayList();
            if (profile.ProfileName.IndexOf("DEFAULT ") >= 0)
            {
                if (profile.ProfileName.Equals("DEFAULT 1Khz"))
                {
                    ProfilesData.Add(new ZapperFrequencies(1000, 90, 60));
                }
                else if (profile.ProfileName.Equals("DEFAULT 2.5Khz"))
                {
                    ProfilesData.Add(new ZapperFrequencies(2500, 90, 60));
                }
                else if (profile.ProfileName.Equals("DEFAULT 30Khz"))
                {
                    ProfilesData.Add(new ZapperFrequencies(30000, 50, 420));
                    ProfilesData.Add(new ZapperFrequencies(30000, 50, 420));
                    ProfilesData.Add(new ZapperFrequencies(30000, 50, 420));
                    ProfilesData.Add(new ZapperFrequencies(10000, 50, 420));
                }
            }
            else
            {
                String baseFolder = @"SD\Sequences\";
                try
                {
                    using (StreamReader sr = new StreamReader(baseFolder + profile.ProfileName + ".txt"))
                    {
                        string data = sr.ReadLine();//reading first line //sequential or random
                        try
                        {
                            while (sr.BaseStream.Position <= sr.BaseStream.Length)
                            {
                                data = sr.ReadLine();
                                string[] splitData = data.Trim().Split('|');
                                if (splitData.Length == 3)
                                {
                                    try
                                    {
                                        long frequency = long.Parse(splitData[0]);
                                        if (isForbiddenFrequency(frequency) == false)
                                        {
                                            ProfilesData.Add(new ZapperFrequencies(frequency, double.Parse(splitData[1]), long.Parse(splitData[2])));
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        Debug.Print("Error when parsing data:" + ex.Message);
                                    }
                                }
                            }
                        }
                        catch (System.NullReferenceException)//happens when reaching end of file
                        {
                            Debug.Print("Reached end of file " + baseFolder + profile.ProfileName);
                        }
                        catch (Exception)
                        {
                            //Debug.Print(ex.Message);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Debug.Print(ex.Message);
                }
            }
            return ProfilesData;
        }

        public int getProfilesSize()
        {
            return Profiles.Count;
        }

        public ZapperProfiles getProfileByIdx(int idx)
        {
            if (idx < Profiles.Count)
            {
                return (ZapperProfiles)(Profiles[idx]);
            }
            else
            {
                return null;
            }
        }
    }
}
